package com.example.netty.nio.groupChat;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

public class GroupchatServer {
    private ServerSocketChannel serverSocketChannel;
    private Selector selector;
    private static final int PORT = 6667;

    public GroupchatServer() throws IOException {
        //通道设置
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.socket().bind(new InetSocketAddress(PORT));
        //selector设置
        selector = Selector.open();
        //将通道注册到selector
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    }

    public void listen() throws IOException {
        //循环监听
        while (true) {
            int selectResult = selector.select(10000);
            if (selectResult > 0) {
                System.out.println("\n监听到事件：");
                Set<SelectionKey> selectionKeys = selector.selectedKeys();

                Iterator<SelectionKey> keyIterator = selectionKeys.iterator();
                while (keyIterator.hasNext()) {
                    SelectionKey key = keyIterator.next();
                    if (key.isAcceptable()) {
                        System.out.println("链接事件，正在创建socketChannel。。。。");
                        SocketChannel socketChannel = serverSocketChannel.accept();
                        socketChannel.configureBlocking(false);
                        socketChannel.register(selector,SelectionKey.OP_READ,ByteBuffer.allocate(1024));
                        System.out.println("创建成功，已注册到selector中，"+
                                socketChannel.getRemoteAddress()+"已上线......");
                    }
                    if (key.isReadable()) {
                        System.out.println("读事件，正在获取socketChannel。。。。");
                        readData(key);
                    }
                    keyIterator.remove();
                }
            }
        }
    }

    private void readData(SelectionKey key) throws IOException {
        SocketChannel socketChannel = null;
        try {
            //接收数据
            socketChannel = (SocketChannel)key.channel();
//            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            ByteBuffer byteBuffer = (ByteBuffer)key.attachment();//在注册的时候如果没有绑定buffer的话，会报错
            socketChannel.read(byteBuffer);
            String message = new String(byteBuffer.array());
            System.out.println("已成功接收客户端的消息："+message.trim());

            //将消息进行转发（要排除自己）
            for (SelectionKey selectionKey : selector.keys()) {
                //不可以在这里直接强转，会报错
                SelectableChannel channel = selectionKey.channel();
                if (channel instanceof SocketChannel && channel != socketChannel) {
                    SocketChannel destSocketChannel = (SocketChannel) channel;

                    destSocketChannel.write(ByteBuffer.wrap(message.getBytes()));
                }
            }
        } catch (IOException e) {
            //读取过程中发生异常，发送方已经断开连接即下线
//            e.printStackTrace();
            System.out.println(socketChannel.getRemoteAddress()+"已下线。。。。");
            //不再监听这个key，关闭通道
            key.cancel();
            socketChannel.close();
        }

    }

    public static void main(String[] args) throws IOException {
        GroupchatServer groupchatServer = new GroupchatServer();
        groupchatServer.listen();
    }
}
